﻿using Games.Basic;
using Games.Data;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;

namespace Games.Common
{
    public abstract class RecordViewModel : BaseViewModel
    {
        bool isBusy = false;
        bool hasMore = true;
        LoadMoreStatus loadStatus;
        int pageIndex = 1;
        int pageSize = 15;
        string title;
        public string Title
        {
            get { return title; }
            set { SetProperty(ref title, value); }
        }
        public bool IsBusy
        {
            get { return isBusy; }
            set { SetProperty(ref isBusy, value); }
        }
        public bool HasMore
        {
            get { return hasMore; }
            set { SetProperty(ref hasMore, value); }
        }
        public LoadMoreStatus LoadStatus
        {
            get { return loadStatus; }
            set { SetProperty(ref loadStatus, value); }
        }
        public RecordViewModel()
        {
            Items = new ObservableCollection<Record>();
            LoadMoreCommand = new Command(async () => await ExecuteLoadMoreCommand());
        }
        public ObservableCollection<Record> Items { get; set; }
        public ICommand LoadMoreCommand { get; set; }
        async Task ExecuteLoadMoreCommand()
        {
            IsBusy = true;
            LoadStatus = LoadMoreStatus.StatusLoading;

            try
            {
                //Items.Clear();
                var items = await GetPage(pageIndex, pageSize);
                foreach(var item in items.Data)
                {
                    Items.Add(item);
                }
                HasMore = items.HasMore;
                pageIndex++;
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
                if(Items.Count == 0)
                {
                    LoadStatus = LoadMoreStatus.StatusNoData;
                }
                else if(HasMore)
                {
                    LoadStatus = LoadMoreStatus.StatusHasData;
                }
                else
                {
                    LoadStatus = LoadMoreStatus.StatusNoMore;
                }
            }
        }
        protected abstract Task<Paged<Record>> GetPage(int pageIndex, int pageSize);
    }

    public class RecordViewModel<T> : RecordViewModel where T : GameRecords, new()
    {
        private readonly Sorter<T> sorter;
        protected IDataBase dataBase;
        public RecordViewModel(Sorter<T> sorter)
        {
            dataBase = DependencyService.Get<IDataBase>();
            this.sorter = sorter ?? Sorter<T>.Default;
        }
        protected override async Task<Paged<Record>> GetPage(int pageIndex, int pageSize)
        {
            var data = await dataBase.GetPageAsync<T>(null, sorter, pageIndex, pageSize);
            return new Paged<Record>
            {
                Data = data.Data.Select(x => x.Convert()).ToList(),
                PageIndex = data.PageIndex,
                PageSize = data.PageSize
            };
        }
    }
}